#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <config.h>
#include <unistd.h>
#include <weather.h>

static PT_currentWeather getCurrentWeatherDataFromXinZhi(char *city);
static PT_futureWeather getFutureWeatherDataFromXinZhi(char *city);
static PT_lifeIndex getLifeIndexDataFromXinZhi(char *city);
static char currentCity[WEATHERSIZE];
pthread_mutex_t weatherMutex = PTHREAD_MUTEX_INITIALIZER;
char *g_pCurrentWeatherBuff;
char *g_pFutureWeatherBuff;
char *g_pLifeIndexBuff;
char g_weatherFlag=0;

static char *CurrentWeatherBuff;
static char *FutureWeatherBuff;
static char *LifeIndexBuff;

static T_weatherOpr weatherData=
{
	.getCurrentWeatherData 	= getCurrentWeatherDataFromXinZhi,
	.getFutureWeatherData 	= getFutureWeatherDataFromXinZhi,
	.getLifeIndexData 		= getLifeIndexDataFromXinZhi,
};

static int parseCurrentWeatherData(char *RecvBuff, PT_currentWeather dataBuff)
{
	cJSON	*json;

	json=cJSON_Parse(RecvBuff); //获取整个大的句柄
	cJSON *arrayItem = cJSON_GetObjectItem(json,"results"); //获取这个对象成员
	cJSON *object = cJSON_GetArrayItem(arrayItem,0);   //因为这个对象是个数组获取，且只有一个元素所以写下标为0获取
	
	/*下面就是可以重复使用cJSON_GetObjectItem来获取每个成员的值了*/
	cJSON *location = cJSON_GetObjectItem(object,"location");
	cJSON *item = cJSON_GetObjectItem(location,"name");
	strcpy(dataBuff->cityName, item->valuestring);
	
	cJSON *now = cJSON_GetObjectItem(object,"now");	
	item = cJSON_GetObjectItem(now,"text");
	strcpy(dataBuff->text, item->valuestring);

	item = cJSON_GetObjectItem(now,"code");
	strcpy(dataBuff->code, item->valuestring);

	item = cJSON_GetObjectItem(now,"temperature");
	strcpy(dataBuff->temperature, item->valuestring);
	
	cJSON_Delete(json);
	return 0;
}

static PT_currentWeather getCurrentWeatherDataFromXinZhi(char *city)
{
	int ret;
	int lenth;
	char RecvBuff[512] = {0};
	char SendBuff[256] = {0};
	PT_currentWeather weatherBuff;

	sprintf(SendBuff,"GET https://api.seniverse.com/v3/weather/now.json?key=%s&location=%s&language=zh-Hans&unit=c\r\n", PRIVATE_KEY, city);

	ret = g_ptNetwork->networkInit();
	if(ret <0)
	{
		fprintf(stderr,"networkInit error\n");
		return NULL;
	}

	ret = g_ptNetwork->networkConnect();
	if(ret <0)
	{
		fprintf(stderr,"networkConnect error\n");
		return NULL;
	}

	ret = g_ptNetwork->networkSend(SendBuff,strlen(SendBuff));
	if(ret <0)
	{
		fprintf(stderr,"networkSend error\n");
		return NULL;
	}

	usleep(50000);  //延时50ms读取网络数据
	lenth = g_ptNetwork->networkRecv(RecvBuff,512);
	if(lenth <=0)
	{
		fprintf(stderr,"networkRecv error\n");
		return NULL;
	}

	ret = g_ptNetwork->networkExit();
	if(ret <0)
	{
		fprintf(stderr,"networkExit error\n");
		return NULL;
	}

	weatherBuff = (PT_currentWeather)CurrentWeatherBuff;

	ret = parseCurrentWeatherData(RecvBuff, weatherBuff);
	if(ret <0)
	{
		fprintf(stderr,"parseCurrentWeatherData error\n");
		return NULL;
	}
	
	return weatherBuff;
}

static int parseFutureWeatherData(char *RecvBuff, PT_futureWeather dataBuff)
{
	cJSON	*json;
	cJSON   *item;
	cJSON   *name;
	PT_futureWeather me;
	int i;

	json=cJSON_Parse(RecvBuff); //获取整个大的句柄
	cJSON *arrayItem = cJSON_GetObjectItem(json,"results"); //获取这个对象成员
	cJSON *object = cJSON_GetArrayItem(arrayItem,0);   //因为这个对象是个数组获取，且只有一个元素所以写下标为0获取
	
	/*下面就是可以重复使用cJSON_GetObjectItem来获取每个成员的值了*/
	//提取城市名
	cJSON *location = cJSON_GetObjectItem(object,"location");
	name = cJSON_GetObjectItem(location,"name");
	
	//提取天气数据
	cJSON *daily = cJSON_GetObjectItem(object,"daily");

	for(i=0;i<3;i++)
	{
		me = (PT_futureWeather)(dataBuff + i);
	
		cJSON *date = cJSON_GetArrayItem(daily,i);

		strcpy(me->cityName, name->valuestring);

		item = cJSON_GetObjectItem(date,"date");
		strcpy(me->date, item->valuestring);

		item = cJSON_GetObjectItem(date,"text_day");
		strcpy(me->text_day, item->valuestring);

		item = cJSON_GetObjectItem(date,"code_day");
		strcpy(me->code_day, item->valuestring);

		item = cJSON_GetObjectItem(date,"text_night");
		strcpy(me->text_night, item->valuestring);

		item = cJSON_GetObjectItem(date,"code_night");
		strcpy(me->code_night, item->valuestring);

		item = cJSON_GetObjectItem(date,"high");
		strcpy(me->high, item->valuestring);

		item = cJSON_GetObjectItem(date,"low");
		strcpy(me->low, item->valuestring);

		item = cJSON_GetObjectItem(date,"rainfall");
		strcpy(me->rainfall, item->valuestring);

		item = cJSON_GetObjectItem(date,"precip");
		strcpy(me->precip, item->valuestring);

		item = cJSON_GetObjectItem(date,"wind_direction");
		strcpy(me->wind_direction, item->valuestring);

		item = cJSON_GetObjectItem(date,"wind_direction_degree");
		strcpy(me->wind_direction_degree, item->valuestring);

		item = cJSON_GetObjectItem(date,"wind_speed");
		strcpy(me->wind_speed, item->valuestring);

		item = cJSON_GetObjectItem(date,"wind_scale");
		strcpy(me->wind_scale, item->valuestring);

		item = cJSON_GetObjectItem(date,"humidity");
		strcpy(me->humidity, item->valuestring);
	}

	cJSON_Delete(json);
	return 0;
}

static PT_futureWeather getFutureWeatherDataFromXinZhi(char *city)
{
	int ret;
	int lenth;
	char RecvBuff[1500] = {0};
	char SendBuff[256] = {0};
	PT_futureWeather weatherBuff;

	sprintf(SendBuff,"GET https://api.seniverse.com/v3/weather/daily.json?key=%s&location=%s&language=zh-Hans&unit=c&start=0&days=5\r\n", PRIVATE_KEY, city);

	ret = g_ptNetwork->networkInit();
	if(ret <0)
	{
		fprintf(stderr,"networkInit error\n");
		return NULL;
	}

	ret = g_ptNetwork->networkConnect();
	if(ret <0)
	{
		fprintf(stderr,"networkConnect error\n");
		return NULL;
	}

	ret = g_ptNetwork->networkSend(SendBuff,strlen(SendBuff));
	if(ret <0)
	{
		fprintf(stderr,"networkSend error\n");
		return NULL;
	}

	usleep(50000);  //延时50ms读取网络数据
	lenth = g_ptNetwork->networkRecv(RecvBuff,1500);
	if(lenth <=0)
	{
		fprintf(stderr,"networkRecv error\n");
		return NULL;
	}

	ret = g_ptNetwork->networkExit();
	if(ret <0)
	{
		fprintf(stderr,"networkExit error\n");
		return NULL;
	}

	weatherBuff = (PT_futureWeather)FutureWeatherBuff;

	ret = parseFutureWeatherData(RecvBuff, weatherBuff);
	if(ret <0)
	{
		fprintf(stderr,"parseFutureWeatherData error\n");
		return NULL;
	}

	return weatherBuff;
}

static int parseLifeIndexData(char *RecvBuff, PT_lifeIndex dataBuff)
{
	cJSON	*json;
	cJSON   *item;
	cJSON   *text;
	cJSON   *name;
	PT_lifeIndex me;
	int i;

	json=cJSON_Parse(RecvBuff); //获取整个大的句柄
	cJSON *arrayItem = cJSON_GetObjectItem(json,"results"); //获取这个对象成员
	cJSON *object = cJSON_GetArrayItem(arrayItem,0);   //因为这个对象是个数组获取，且只有一个元素所以写下标为0获取
	
	/*下面就是可以重复使用cJSON_GetObjectItem来获取每个成员的值了*/
	//提取城市名
	cJSON *location = cJSON_GetObjectItem(object,"location");
	name = cJSON_GetObjectItem(location,"name");
	
	//提取天气数据
	cJSON *suggestion = cJSON_GetObjectItem(object,"suggestion");

	for(i=0;i<5;i++)
	{
		me = (PT_lifeIndex)(dataBuff + i);

		strcpy(me->cityName, name->valuestring);
		cJSON *date = cJSON_GetArrayItem(suggestion,i);

		item = cJSON_GetObjectItem(date,"date");
		strcpy(me->date, item->valuestring);

		item = cJSON_GetObjectItem(date,"ac");
		text = cJSON_GetObjectItem(item,"brief");
		strcpy(me->ac, text->valuestring);

		item = cJSON_GetObjectItem(date,"air_pollution");
		text = cJSON_GetObjectItem(item,"brief");
		strcpy(me->air_pollution, text->valuestring);

		item = cJSON_GetObjectItem(date,"airing");
		text = cJSON_GetObjectItem(item,"brief");
		strcpy(me->airing, text->valuestring);

		item = cJSON_GetObjectItem(date,"allergy");
		text = cJSON_GetObjectItem(item,"brief");
		strcpy(me->allergy, text->valuestring);

		item = cJSON_GetObjectItem(date,"beer");
		text = cJSON_GetObjectItem(item,"brief");
		strcpy(me->beer, text->valuestring);

		item = cJSON_GetObjectItem(date,"boating");
		text = cJSON_GetObjectItem(item,"brief");
		strcpy(me->boating, text->valuestring);

		item = cJSON_GetObjectItem(date,"car_washing");
		text = cJSON_GetObjectItem(item,"brief");
		strcpy(me->car_washing, text->valuestring);

		item = cJSON_GetObjectItem(date,"comfort");
		text = cJSON_GetObjectItem(item,"brief");
		strcpy(me->comfort, text->valuestring);

		item = cJSON_GetObjectItem(date,"dressing");
		text = cJSON_GetObjectItem(item,"brief");
		strcpy(me->dressing, text->valuestring);

		item = cJSON_GetObjectItem(date,"fishing");
		text = cJSON_GetObjectItem(item,"brief");
		strcpy(me->fishing, text->valuestring);

		item = cJSON_GetObjectItem(date,"flu");
		text = cJSON_GetObjectItem(item,"brief");
		strcpy(me->flu, text->valuestring);

		item = cJSON_GetObjectItem(date,"kiteflying");
		text = cJSON_GetObjectItem(item,"brief");
		strcpy(me->kiteflying, text->valuestring);

		item = cJSON_GetObjectItem(date,"makeup");
		text = cJSON_GetObjectItem(item,"brief");
		strcpy(me->makeup, text->valuestring);

		item = cJSON_GetObjectItem(date,"mood");
		text = cJSON_GetObjectItem(item,"brief");
		strcpy(me->mood, text->valuestring);

		item = cJSON_GetObjectItem(date,"morning_sport");
		text = cJSON_GetObjectItem(item,"brief");
		strcpy(me->morning_sport, text->valuestring);

		item = cJSON_GetObjectItem(date,"road_condition");
		text = cJSON_GetObjectItem(item,"brief");
		strcpy(me->road_condition, text->valuestring);

		item = cJSON_GetObjectItem(date,"shopping");
		text = cJSON_GetObjectItem(item,"brief");
		strcpy(me->shopping, text->valuestring);

		item = cJSON_GetObjectItem(date,"sport");
		text = cJSON_GetObjectItem(item,"brief");
		strcpy(me->sport, text->valuestring);

		item = cJSON_GetObjectItem(date,"sunscreen");
		text = cJSON_GetObjectItem(item,"brief");
		strcpy(me->sunscreen, text->valuestring);

		item = cJSON_GetObjectItem(date,"traffic");
		text = cJSON_GetObjectItem(item,"brief");
		strcpy(me->traffic, text->valuestring);

		item = cJSON_GetObjectItem(date,"umbrella");
		text = cJSON_GetObjectItem(item,"brief");
		strcpy(me->umbrella, text->valuestring);

		item = cJSON_GetObjectItem(date,"uv");
		text = cJSON_GetObjectItem(item,"brief");
		strcpy(me->uv, text->valuestring);		
	}

	cJSON_Delete(json);
	return 0;
}


static PT_lifeIndex getLifeIndexDataFromXinZhi(char *city)
{
	int ret;
	int lenth;
	char RecvBuff[18000] = {0};
	char SendBuff[256] = {0};
	PT_lifeIndex weatherBuff;

	sprintf(SendBuff,"GET https://api.seniverse.com/v3/life/suggestion.json?key=%s&location=%s&language=zh-Hans&days=5\r\n", PRIVATE_KEY, city);

	ret = g_ptNetwork->networkInit();
	if(ret <0)
	{
		fprintf(stderr,"networkInit error\n");
		return NULL;
	}

	ret = g_ptNetwork->networkConnect();
	if(ret <0)
	{
		fprintf(stderr,"networkConnect error\n");
		return NULL;
	}

	ret = g_ptNetwork->networkSend(SendBuff,strlen(SendBuff));
	if(ret <0)
	{
		fprintf(stderr,"networkSend error\n");
		return NULL;
	}

	usleep(250000);  //延时250ms读取网络数据
	lenth = g_ptNetwork->networkRecv(RecvBuff,18000);
	if(lenth <=0)
	{
		fprintf(stderr,"networkRecv error\n");
		return NULL;
	}

	ret = g_ptNetwork->networkExit();
	if(ret <0)
	{
		fprintf(stderr,"networkExit error\n");
		return NULL;
	}

	weatherBuff = (PT_lifeIndex)LifeIndexBuff;

	ret = parseLifeIndexData(RecvBuff, weatherBuff);
	if(ret <0)
	{
		fprintf(stderr,"parseLifeIndexData error\n");
		return NULL;
	}

	return weatherBuff;
}


static void *weatherHandler(void *ptr)
{
	PT_currentWeather currentWeather;
	PT_futureWeather  futureWeather;
	PT_lifeIndex	  lifeIndex;
	int lenth1 = sizeof(T_currentWeather);
	int lenth2 = sizeof(T_futureWeather)*3;
	int lenth3 = sizeof(T_lifeIndex)*5;

	while(1)
	{
		g_weatherFlag =0;
		currentWeather 	= weatherData.getCurrentWeatherData(currentCity);
		if(currentWeather ==NULL)
		{
			fprintf(stdout, "getCurrentWeatherData error\n");
			break;
		}
		futureWeather = weatherData.getFutureWeatherData(currentCity);
		if(futureWeather ==NULL)
		{
			fprintf(stdout, "getFutureWeatherData error\n");
			break;
		}
		lifeIndex = weatherData.getLifeIndexData(currentCity);
		if(lifeIndex ==NULL)
		{
			fprintf(stdout, "getLifeIndexData error\n");
			break;
		}

		//数据更新
		pthread_mutex_lock(&weatherMutex);
		memcpy(g_pCurrentWeatherBuff, currentWeather, lenth1);
		memcpy(g_pFutureWeatherBuff, futureWeather, lenth2);
		memcpy(g_pLifeIndexBuff, lifeIndex, lenth3);
		pthread_mutex_unlock(&weatherMutex);
		g_weatherFlag =1;
		sleep(600);//测试600S延时     10min请求一次数据
	}

	pthread_exit(NULL);
}

int weatherThreadInit(void)
{
	int ret;

	//设置默认城市
	memset(currentCity, 0, WEATHERSIZE);
	strcpy(currentCity, DEFAULT_CITY);

	//全局空间
	g_pCurrentWeatherBuff = malloc(sizeof(T_currentWeather));
	if(g_pCurrentWeatherBuff ==NULL)
	{
		fprintf(stdout, "malloc error\n");
		return -1;
	}

	g_pFutureWeatherBuff  = malloc(sizeof(T_futureWeather)*3);
	if(g_pFutureWeatherBuff ==NULL)
	{
		fprintf(stdout, "malloc error\n");
		return -1;
	}

	g_pLifeIndexBuff = malloc(sizeof(T_lifeIndex)*5);
	if(g_pLifeIndexBuff ==NULL)
	{
		fprintf(stdout, "malloc error\n");
		return -1;
	}

	//局部空间
	CurrentWeatherBuff = malloc(sizeof(T_currentWeather));
	if(CurrentWeatherBuff ==NULL)
	{
		fprintf(stdout, "malloc error\n");
		return -1;
	}

	FutureWeatherBuff  = malloc(sizeof(T_futureWeather)*3);
	if(FutureWeatherBuff ==NULL)
	{
		fprintf(stdout, "malloc error\n");
		return -1;
	}
	
	LifeIndexBuff = malloc(sizeof(T_lifeIndex)*5);
	if(LifeIndexBuff ==NULL)
	{
		fprintf(stdout, "malloc error\n");
		return -1;
	}
	
	ret = pthread_create(&weatherData.tid,NULL,weatherHandler,NULL);
	if(ret !=0)
	{
		fprintf(stderr,"pthread_create error %s\n",strerror(errno));
		return -1;
	}
	return 0;
}

int weatherThreadExit(void)
{
	free(g_pCurrentWeatherBuff);
	free(g_pFutureWeatherBuff);
	free(g_pLifeIndexBuff);
	free(CurrentWeatherBuff);
	free(FutureWeatherBuff);
	free(LifeIndexBuff);
	pthread_cancel(weatherData.tid);
	pthread_join(weatherData.tid,NULL);
	pthread_mutex_unlock(&weatherMutex);
	pthread_mutex_destroy(&weatherMutex);

	return 0;
}

int setCurrentCity(char *city)
{
	PT_currentWeather currentWeather;
	PT_futureWeather  futureWeather;
	PT_lifeIndex	  lifeIndex;
	int lenth1 = sizeof(T_currentWeather);
	int lenth2 = sizeof(T_futureWeather)*3;
	int lenth3 = sizeof(T_lifeIndex)*5;

	//设置城市
	memset(currentCity, 0, WEATHERSIZE);
	strcpy(currentCity, city);

	//获取天气数据
	currentWeather 	= weatherData.getCurrentWeatherData(currentCity);
	if(currentWeather ==NULL)
	{
		fprintf(stdout, "getCurrentWeatherData error\n");
		return -1;
	}
		
	futureWeather = weatherData.getFutureWeatherData(currentCity);
	if(futureWeather ==NULL)
	{
		fprintf(stdout, "getFutureWeatherData error\n");
		return -1;
	}
		
	lifeIndex = weatherData.getLifeIndexData(currentCity);
	if(lifeIndex ==NULL)
	{
		fprintf(stdout, "getLifeIndexData error\n");
		return -1;
	}

	//数据更新
	pthread_mutex_lock(&weatherMutex);
	memcpy(g_pCurrentWeatherBuff, currentWeather, lenth1);
	memcpy(g_pFutureWeatherBuff, futureWeather, lenth2);
	memcpy(g_pLifeIndexBuff, lifeIndex, lenth3);	
	pthread_mutex_unlock(&weatherMutex);

	return 0;
}

